#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <pthread.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "global.h"
#include "constantes.h"
#include "sockets.h"
#include "NIPC.h"
#include "listas.h"
#include "sincronizador.h"


extern int numeroSincro;
extern int contador;
int owner;

	
void *syncer(void *args) {
    
	disco * discoASincronizar = (struct DiscoConocido *) args;	
	char* buff=(char *)malloc(600);
	char* sSocket=(char *)malloc(20);
	int contador;
	char* sContador=(char*)malloc(20);
	char* sAux=(char*)malloc(20);
	int tamanio_buff;
	int payload;
	int flag;
	int sectoresSolicitados=0;
	
	while(discoASincronizar->sectores < 1048576)
	{
		
		if(sectoresSolicitados<1048576){
		
			
			/*disco *dsk = (disco *)elegirDisco(sectoresSolicitados);*/
			disco *dsk=(disco*)BuscarDiscoPorNombre("Disco2");
			
			if(socketCanSend(dsk->iSocketHDAParaDA)){
			
				if(pthread_mutex_lock(&(mutex3))!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}
					
				contador++;			
					
				if(pthread_mutex_unlock(&(mutex3))!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}


				intacad(contador,sContador);
				dsk->pendings++;
				memset(sAux,'\0',20);
				intacad(sectoresSolicitados,sAux);	
				payload=READ_SECTORSYNC_REQUEST;
				tamanio_buff = strlen(sContador) + 1 + strlen(sAux) + 2 ;
				char* buffer = (char *) malloc (sizeof(char) * tamanio_buff);
				strcpy(buffer, sContador);
				strcat(buffer, ",");
				strcat(buffer, sAux);
				strcat(buffer, ";");
				InfoIPC rInfoIPC3;
				rInfoIPC3.payLoadLength=tamanio_buff;
				generarStructIPC(buffer,payload,&rInfoIPC3);			
				enviarIPC(dsk->iSocketHDAParaDA,&rInfoIPC3);
				/*send(dsk->iSocketHDAParaDA,rInfoIPC3,530,MSG_WAITALL);*/
				
				pedido * NodoDescriptores = (struct ListaIDdescriptors *)malloc(sizeof(struct ListaIDdescriptors));
				
				intacad(discoASincronizar->iSocketHDAParaDA,sSocket);
				strcpy(NodoDescriptores->sSocketPorElCualResponder,sSocket);
				strcpy(NodoDescriptores->discoAsignado,dsk->sNombre);
				strcpy(NodoDescriptores->sDescriptorID_delPedido,sContador);
				NodoDescriptores->numeroSector=sectoresSolicitados;
				NodoDescriptores->estado=1;
				NodoDescriptores->operacion=0;
				NodoDescriptores->owner=owner;
				NodoDescriptores->Sgt = NULL;
				NodoDescriptores->Ant = NULL;


				if(pthread_mutex_lock(&mutex)!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}
				
				AgregarAColaDePedidosADisco(&NodoDescriptores,&(colaGlobal),&(colaGlobal_Ult));
				
				if(pthread_mutex_unlock(&mutex)!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}
				
				
				sectoresSolicitados++;
					
				free(buffer);
			
			}
			
		}

		int readable_bytes=0;
	
		if(ioctl(discoASincronizar->iSocketHDAParaDA,FIONREAD,&readable_bytes)==0){
	
			
			
			if(readable_bytes>=530){
		
				
				InfoIPC rInfoIPC8;
				recibirIPC(discoASincronizar->iSocketHDAParaDA,&rInfoIPC8);
				recv(discoASincronizar->iSocketHDAParaDA,buff,530,MSG_WAITALL);
				free(rInfoIPC8.payload);

				if(pthread_mutex_lock(&mutex)!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}
		
				pedido* nodo=SacarNodoDescriptoresDeLista(&(colaGlobal),&(colaGlobal_Ult));
				
				if(pthread_mutex_unlock(&mutex)!=0){
					perror("pthread_mutex_lock");
					exit(EXIT_FAILURE);
				}
		
				free(nodo);
				discoASincronizar->sectores++;
				
			}
		}
		
		
		if(discoASincronizar->sectores==100000 || discoASincronizar->sectores==200000 || discoASincronizar->sectores==300000  || discoASincronizar->sectores==400000  || discoASincronizar->sectores==500000  || discoASincronizar->sectores==600000  || discoASincronizar->sectores==700000  || discoASincronizar->sectores==800000  || discoASincronizar->sectores==900000  || discoASincronizar->sectores==1000000 )
			printf("Se sincronizaron los primeros %i sectores\n",discoASincronizar->sectores);
	
	}
	
	free(sAux);
	free(sContador);
	
	printf("Se finalizo la sincronizacion del disco %s\n", discoASincronizar->sNombre);
	discoASincronizar->Estado = LISTO;
	printf("DISCO LISTO\n");

}


